import React from 'react';
import * as PIXI from 'pixi.js';
import { withTranslation, WithTranslation } from 'react-i18next';
// import { END_STATUS, SPEED_LEVEL, Game } from '../../services/game-engine';
import GameContainer from '../../components/game-container';
// import game from '../../services/game.js'

import styles from './GamePage.module.css';



interface ResourceImage {
  src: string;
  top: number;
  left: number;
  width: number;
  height: number;
}

interface Resources {
  // 掉落元素图片
  fallingItemElement: ResourceImage;
  // 障碍物
  fallingBlockElement: ResourceImage;
  // 接收掉落元素图片
  receiveElement: ResourceImage;
  // 得分 +1 图片
  scoreAddElement: ResourceImage;
}

interface CallbackListener {
  (n: number): void;
}

interface GameProps {
  /** 游戏运行容器元素 */
  el: null | HTMLElement;
  /** 所有资源 */
  resources: Resources;
  /** 限时 */
  timeLimit?: number;
  /** 速度等级 */
  speedLevel: SPEED_LEVEL;
  /** 时间变化监听 */
  timeListeners?: CallbackListener[];
  /** 得分变化监听 */
  scoreListeners?: CallbackListener[];
  /** 游戏结束 */
  gameOver?: ({ status: END_STATUS, score: number }) => void;
}

enum FALL_TYPES {
  ITEM = 'fallingItemElement',
  BLOCK = 'fallingBlockElement',
}

interface FallingSpriteItem {
  type: FALL_TYPES;
  sprite: PIXI.Sprite;
  speed: number;
}

/** 碰撞判断 */
// const bump = new Bump(PIXI);

const ZONGZI = 'https://apg-kangkang-tea.oss-cn-hangzhou.aliyuncs.com/apg-kangkang-tea/tmp/zongzi.png';

export enum STAGE {
  WAITING = 'waiting',
  RUNNING = 'running',
  PAUSE = 'pause',
  STOP = 'stop',
}

export enum SPEED_LEVEL {
  SLOW = 'slow',
  MIDDLE = 'middle',
  FAST = 'fast',
}

export enum END_STATUS {
  TIMEOUT = 'timeout',
  FAILED = 'failed',
}

/** 不同速度对设备高度等分, 动态获取速度 */
const SPEED_PIECE = {
  [SPEED_LEVEL.SLOW]: 110,
  [SPEED_LEVEL.MIDDLE]: 90,
  [SPEED_LEVEL.FAST]: 70,
};

const defaultResource = () => ({
  src: '',
  top: 0,
  left: 0,
  width: 0,
  height: 0,
});
const createDefaultProps = (): GameProps => ({
  el: null,
  resources: {
    fallingItemElement: defaultResource(),
    fallingBlockElement: defaultResource(),
    receiveElement: defaultResource(),
    scoreAddElement: defaultResource(),
  },
  timeLimit: 30,
  speedLevel: SPEED_LEVEL.MIDDLE,
  timeListeners: [],
  scoreListeners: [],
});

class GamePageComponent extends React.Component<WithTranslation> {

  private refView: any = React.createRef();

  private app: any;
  
  private isInit: boolean = false;

  private sprites: object = {};

  private textures: object = {};

  private fallingElements: Array<any> = [];

  private movingGift: any;

  private plusElements: PIXI.Sprite[] = [];

  /** 得分元素追加定时器 */
  private itemTimer: NodeJS.Timeout | null = null;

  /** 障碍物追加定时器 */
  private blockTimer: NodeJS.Timeout | null = null;

  /** 生成粽子基础间隔时间 */
  private baseAppendTime = 300;

  /** 生成粽子变动时间 */
  private dynamicAppendTime = 300;


  componentDidMount() {
    console.log('Did mount!');

    this.createGame();
    this.init();
  }

  private handleUpdateTimeUsed() {

  }

  private handleUpdateScore() {

  }

  private handleGameOver() {

  }

  private addBackground() {

  }

  /** 读取当前画布尺寸 */
  private getViewSize() {
    const that = this;
    const offsetWidth = that.refView.current.offsetWidth;
    const offsetHeight = that.refView.current.offsetHeight;

    return {
      width: offsetWidth,
      height: offsetHeight,
    };
  }

  /** 获取图片代理地址 */
  private createProxyImageSprite = (src: string) =>
  PIXI.Texture.from(src);


  /** 根据类型生成掉落 sprite(得分元素 + 障碍物) */
  private createFallingSprite = (type: FALL_TYPES) => {
    const texture = this.createProxyImageSprite(ZONGZI);
    const { width, height } ={ width: 165, height: 141 };
    const sprite = PIXI.Sprite.from(ZONGZI);

    const speed = 20;

    sprite.width = width;
    sprite.height = height;
    const viewSize = this.getViewSize();
    sprite.x = Math.floor(Math.random() * (viewSize.width - width));
    sprite.y = -height + 200;
    switch (type) {
      case FALL_TYPES.BLOCK:
        break;
      default:
        // FALL_TYPES.ITEM
        sprite.anchor.set(0.5);
        sprite.rotation = Math.PI / 2 - Math.PI * Math.random();
    }

    this.app.ticker.add(() => {
      sprite.y += 0.1 * 10;
    });

    this.app.stage.addChild(sprite);
    this.fallingElements.push({
      type,
      sprite,
      speed,
    });

    return sprite;
  };

  /** 随机新增掉落物时间 */
  private getAppendTime() {
    // 获取"慢速"与"当前速度"比例, 比例越小, 表示当前速度越快
    // const zoom = this.getSpeed(SPEED_LEVEL.SLOW) / this.speed;
    const zoom = 1;
    // 速度愉快, 生成掉落物间隔越短
    return Math.floor(
      (Math.random() * this.dynamicAppendTime + this.baseAppendTime) * zoom
    );
  }

  /** 追加积分掉落物 */
  private appendItemSprite = () => {
    const type = FALL_TYPES.ITEM;
    this.createFallingSprite(type);
    const duration = this.getAppendTime();

    this.clearItemTimer();
    this.itemTimer = setTimeout(() => {
      this.appendItemSprite();
    }, duration);
  };

  /** 清理物品掉落定时器 */
  private clearItemTimer = () => {
    if (this.itemTimer) {
      clearTimeout(this.itemTimer);
      this.itemTimer = null;
    }
  };


  private addElements() {
    const loader = new PIXI.Loader();
    // Chainable `add` to enqueue a resource
    loader.add('bunny', 'https://apg-kangkang-tea.oss-cn-hangzhou.aliyuncs.com/apg-kangkang-tea/tmp/zongzi.png')
    .add('test2', 'https://apg-kangkang-tea.oss-cn-hangzhou.aliyuncs.com/apg-kangkang-tea/tmp/zongzi.png');
    
    loader.load((loader, resources: any) => {
      // resources is an object where the key is the name of the resource loaded and the value is the resource object.
      // They have a couple default properties:
      // - `url`: The URL that the resource was loaded from
      // - `error`: The error that happened when trying to load (if any)
      // - `data`: The raw data that was loaded
      // also may contain other properties based on the middleware that runs.
      this.textures['bunny'] = new PIXI.Texture(resources.bunny.texture);
      
      this.sprites['bunny'] = new PIXI.TilingSprite(resources.bunny.texture, 165 , 141);
      this.sprites['bunny'].scale.set(0.5, 0.5);
      this.sprites['spaceship'] = new PIXI.TilingSprite(resources.test2.texture);
    });

    // throughout the process multiple signals can be dispatched.
    loader.onProgress.add(() => {}); // called once per loaded/errored file
    loader.onError.add(() => {}); // called once per errored file
    loader.onLoad.add(() => {}); // called once per loaded file
    loader.onComplete.add(() => {
      this.movingGift = this.sprites['bunny'];
      this.movingGift.x = 20;
      this.movingGift.y = 20;
      this.app.stage.addChild(this.movingGift);

      this.appendItemSprite();

      // this.app.ticker.add(() => {
      //   const that = this;
       
      //   // just for fun, let's rotate mr rabbit a little
      //   that.movingGift.y += 0.1 * 10;
      // });
    }); // called once when the queued resources all load.
  }

  private initGameSetting() {
    const { app } = this;

    app.resizeTo = this.refView.current as HTMLElement;
    app.resize();
    app.stage.interactive = true;
    if (!('events' in app.renderer) && 'addSystem' in app.renderer) {
      // app.renderer.addSystem(EventSystem as any, 'events');
    }
    // 初始化速度
    const speed = 100;
    // 初始化增速
    // this.increment = (this.increment * speed) / this.speed;
    // // 配置初始速度
    // this.speed = speed;

    this.addElements();
    
  }

  private initDragElement() {
    
  }

  /** 游戏初始化 */
  public init() {
    if (this.isInit) return;
 
    this.initGameSetting();
    this.initDragElement();
  }

  private createGame() {
    // Create the application helper and add its render target to the page

    let app = new PIXI.Application({
      width: 414,
      height: 896,  
      antialias: true, // 消锯齿
      autoDensity: true,
      backgroundAlpha: 0
    });
    this.app = app;
    document.getElementById('myCanvas')?.appendChild(app.view);
    
    // Create window frame
    let frame = new PIXI.Graphics();
    // frame.beginFill(0x666666);
    frame.lineStyle({ color: 0xffffff, width: 4, alignment: 0 });
    // frame.drawRect(0, 0, 208, 208);
    frame.position.set(320 - 100, 180 - 100);
    app.stage.addChild(frame);

    return;
    
    // Create a graphics object to define our mask
    let mask = new PIXI.Graphics();
    // Add the rectangular area to show
    // mask.beginFill(0xffffff);
    // mask.drawRect(0,0,200,200);
    mask.endFill();
    
    // Add container that will hold our masked content
    let maskContainer = new PIXI.Container();
    // Set the mask to use our graphics object from above
    maskContainer.mask = mask;
    // Add the mask as a child, so that the mask is positioned relative to its parent
    maskContainer.addChild(mask);
    // Offset by the window's frame width
    maskContainer.position.set(4,4);
    // And add the container to the window!
    frame.addChild(maskContainer);
    
    // Create contents for the masked container
    let text = new PIXI.Text(
      'This text will scroll up and be masked, so you can see how masking works.  Lorem ipsum and all that.\n\n' +
      'You can put anything in the container and it will be masked!',
      {
        fontSize: 24,
        fill: 0x1010ff,
        wordWrap: true,
        wordWrapWidth: 180
      }
    );
    text.x = 10;
    maskContainer.addChild(text);
    
    // Add a ticker callback to scroll the text up and down
    let elapsed = 0.0;
    app.ticker.add((delta) => {
      // Update the text's y coordinate to scroll it
      elapsed += delta;
      text.y = 10 + -100.0 + Math.cos(elapsed/50.0) * 100.0;
    });

  }

  render() {
    // return <GameContainer           
    //   timeLimit={3000}
    //   speedLevel={SPEED_LEVEL.MIDDLE}
    //   wrappedGame={game => {
    //     this.game = game;
    //   }}
    //   onUpdateTime={this.handleUpdateTimeUsed}
    //   onUpdateScore={this.handleUpdateScore}
    //   onGameOver={this.handleGameOver}>
    //   <div>hello</div>
    // </GameContainer>;

    return <div ref={this.refView}  id="myCanvas" className={styles['container']} style={{ "backgroundImage": "url(https://apg-kangkang-tea.oss-cn-hangzhou.aliyuncs.com/apg-kangkang-tea/tmp/12ea2822-1a1a-4458-9e13-e93d81042abc.png)"}}>

      
    </div>
  }
};


export const GamePage = withTranslation()(GamePageComponent);